package com.kitty.game.rank.service.handler;

import com.kitty.game.role.model.Role;
import com.kitty.common.utils.SpringUtils;
import com.kitty.game.enter.FiedValue;
import com.kitty.game.rank.model.PersonInfo;
import com.kitty.game.rank.message.RespRankTopUser;
import com.kitty.game.rank.model.Range;
import com.kitty.game.rank.model.RankType;
import com.kitty.game.rank.model.pojo.DataUnit;
import com.kitty.game.rank.model.pojo.RankGroupListData;
import com.kitty.game.rank.model.record.RankRecord;
import com.kitty.game.rank.model.record.ZhengDaoRankRecord;
import com.kitty.game.utils.Const;
import lombok.extern.slf4j.Slf4j;
import org.nutz.dao.Dao;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**证道排行榜处理类*/
@Component
@Slf4j
public class ZhengDaoRankHandler extends GroupRangeRankHandler {
    /**职业组*/
    private List<Byte> polarGroups = new ArrayList();
    private Map<Short, Byte> type2Groups = new HashMap<>();
    /**等级段*/
    private List<Range<Short>> levelRanges = new ArrayList<>();

    /**初始化职业组*/
    @PostConstruct
    private void initGroups() {
        polarGroups.add(Const.SCHOOL_METAL);
        polarGroups.add(Const.SCHOOL_WOOD);
        polarGroups.add(Const.SCHOOL_WATER);
        polarGroups.add(Const.SCHOOL_FIRE);
        polarGroups.add(Const.SCHOOL_EARTH);
    }

    /**初始化请求类型与职业映射关系*/
    @PostConstruct
    private void initType2Groups() {
        type2Groups.put((short) 1101, Const.SCHOOL_METAL);
        type2Groups.put((short) 1102, Const.SCHOOL_WOOD);
        type2Groups.put((short) 1103, Const.SCHOOL_WATER);
        type2Groups.put((short) 1104, Const.SCHOOL_FIRE);
        type2Groups.put((short) 1105, Const.SCHOOL_EARTH);
    }

    /**初始化等级段*/
    @PostConstruct
    private void initRange() {
        levelRanges.add(new Range((short)70, (short)79));
        levelRanges.add(new Range((short) 80, (short) 89));
        levelRanges.add(new Range((short) 90, (short) 99));
        levelRanges.add(new Range((short) 100, (short) 109));
        levelRanges.add(new Range((short) 110, (short) 119));
        levelRanges.add(new Range((short) 120, (short) 139));
    }

    @Override
    public void init() {
        Dao dao = SpringUtils.getBean(Dao.class);
        RankGroupListData<ZhengDaoRankRecord> zhengDaoRankData = dao.fetch(RankGroupListData.class, RankType.ZHENG_DAO.name());
        if (zhengDaoRankData != null) {
            zhengDaoRankData.doAfterInit(ZhengDaoRankRecord.class);
            List<DataUnit> rankData = zhengDaoRankData.getRankData();
            for (DataUnit dataUnit : rankData) {
                List<String> list = parseSaveKey(dataUnit.getKey());
                byte polar = Byte.parseByte(list.get(0).trim());
                String levelRange = list.get(1).trim();
                for (RankRecord record : dataUnit.getRecords()) {
                    ZhengDaoRankRecord zhengDaoRankRecord = (ZhengDaoRankRecord) record;
                    update(polar, levelRange, zhengDaoRankRecord.getGid(), zhengDaoRankRecord);
                }
            }
        }
    }

    private String getLevelRange(Range range) {
        return range.getMin() + "-" + range.getMax();
    }

    /**找到角色对应的分段*/
    public String getLevelRange(Role role) {
        short roleLevel = role.getLevel();
        Range<Short> range = getRange(roleLevel);
        if (range != null) {
            return getLevelRange(range);
        }
        return null;
    }

    private Range<Short> getRange(short roleLevel) {
        for (Range<Short> range : levelRanges) {
            if (roleLevel >= range.getMin() && roleLevel <= range.getMax()) {
                return range;
            }
        }

        return null;
    }

    public void save() {
        List<DataUnit> rankData = new ArrayList<>();
        for (byte polar : polarGroups) {
            for (Range<Short> range : levelRanges) {
                String levelRange = getLevelRange(range);
                List<RankRecord> records = getRecordsFrom(polar, levelRange, 0, getRankSize());
                if (records == null || records.size() == 0) {continue ;}

                String saveKey = getSaveKey(polar, levelRange);
                DataUnit dataUnit = new DataUnit(saveKey, records);
                rankData.add(dataUnit);
            }
        }

        if (rankData.size() <= 0) {return ;}

        RankGroupListData<ZhengDaoRankRecord> zhengDaoRankData = new RankGroupListData<>(RankType.ZHENG_DAO, rankData);
        zhengDaoRankData.doBeforeSave();
        Dao dao = SpringUtils.getBean(Dao.class);
        dao.insertOrUpdate(zhengDaoRankData);
    }

    @PreDestroy
    private void shutDown() {
        save();
        log.error("[{}]保存数据后关闭", this.getClass().getSimpleName());
    }

    private String getSaveKey(byte polar, String levelRange) {
        return polar + "_" + levelRange;
    }

    private List<String> parseSaveKey(String key) {
        String[] arrays = key.split("_", 2);
        return Arrays.asList(arrays);
    }

    public RespRankTopUser getRankResponse(short type, String range) {
        RespRankTopUser respRankTopUser = new RespRankTopUser();
        respRankTopUser.setType(type);
        respRankTopUser.setCookie(new Long(System.currentTimeMillis() / 1000).intValue());
        respRankTopUser.setList(new ArrayList<>());
        byte polar = type2Groups.get(type);
        List<PersonInfo> personInfoList = getPersonInfoList(getRecordsFrom(polar, range, 0, getRankSize()));
        respRankTopUser.setList(personInfoList);
        respRankTopUser.setSize((short) respRankTopUser.getList().size());
        String[] levels = range.split("-");
        respRankTopUser.setMin(Short.parseShort(levels[0]));
        respRankTopUser.setMax(Short.parseShort(levels[1]));
        return respRankTopUser;
    }

    private List<PersonInfo> getPersonInfoList(List<RankRecord> records) {
        List<PersonInfo> list = new ArrayList<>(records.size());
        for (RankRecord rankRecord : records) {
            ZhengDaoRankRecord taoRankRecord = (ZhengDaoRankRecord)rankRecord;
            PersonInfo personInfo = new PersonInfo();
            personInfo.setList(new ArrayList<>());
            personInfo.getList().add(new FiedValue(305, taoRankRecord.getGid()));
            personInfo.getList().add(new FiedValue(855, taoRankRecord.getPartyName()));
            personInfo.getList().add(new FiedValue(1, taoRankRecord.getName()));
            personInfo.getList().add(new FiedValue(938, taoRankRecord.getTime()));
            personInfo.getList().add(new FiedValue(31, taoRankRecord.getLevel()));
            list.add(personInfo);
        }
        return list;
    }

    public void update(String gid, byte polar, short level, String partyName, String name, short roleIcon, int time) {
        Range range = getRange(level);
        if (range == null) {return ;}

        String levelRange = getLevelRange(range);
        this.update(polar, levelRange, gid, new ZhengDaoRankRecord(gid, time, partyName, name, roleIcon, level));
    }

    /**角色升级跨等级段处理*/
    public void handleRoleUpgrade(Role role, short oldLevel, short newLevel) {
        /**判断角色是否跨等级段，是的话则从旧等级段排行榜删除，加入新等级段排行榜*/

        Range oldRange = getRange(oldLevel);
        Range newRange = getRange(newLevel);
        /**同一等级段时，返回*/
        if (oldRange != null && oldRange.equals(newRange)) {return ;}

        if (oldRange != null) {
            byte polar = (byte) role.getPolar();
            String oldLevelRange = getLevelRange(oldRange);

            ZhengDaoRankRecord rankRecord = (ZhengDaoRankRecord)remove(polar, oldLevelRange, role.getGid());
            if (rankRecord != null) {
                String newLevelRange = getLevelRange(newRange);
                this.update(polar, newLevelRange, role.getGid(), new ZhengDaoRankRecord(role.getGid(), rankRecord.getTime(), role.getPartyName(), role.getName(), role.getRoleIcon(), role.getLevel()));
            }
        }
    }
}
